package org.cloudbus.cloudsim.examples.power.parallel;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class ParallelHelper {

	public ParallelHelper() {
		super();
	}

	private String[] deleteElementEmpty(String[] input) {
		List<String> temp = new ArrayList<String>();
		String[] rs = null;
		for (int i = 0; i < input.length; i++) {
			if (input[i].trim().isEmpty()) {
				continue;
			}
			temp.add(input[i]);
		}
		rs = new String[temp.size()];
		for (int i = 0; i < temp.size(); i++) {
			rs[i] = temp.get(i);
		}
		return rs;
	}

	private ExtraFieldInfo parseExtraFields(String strLine) {
		int mark = strLine.indexOf(":");
		String name = "";
		String value = "";
		name = strLine.substring(1, mark).trim();
		value = strLine.substring(mark + 1, strLine.length()).trim();
		return new ExtraFieldInfo(name, value);
	}

	public List<MainFieldInfo> getMainFields(String inputFile)
			throws IOException {
		List<MainFieldInfo> lineInfos = new ArrayList<MainFieldInfo>();
		MainFieldInfo info = null;
		FileInputStream fileInputStream = new FileInputStream(inputFile);
		DataInputStream dataInputStream = new DataInputStream(fileInputStream);
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				dataInputStream));
		String strLine;
		while ((strLine = reader.readLine()) != null) {
			if (strLine.contains(";")) {
				continue;
			}
			String[] arrayStrings = strLine.trim().split(" ");
			arrayStrings = this.deleteElementEmpty(arrayStrings);

			info = new MainFieldInfo(Integer.parseInt(arrayStrings[0]),
					Double.parseDouble(arrayStrings[1]),
					Double.parseDouble(arrayStrings[2]),
					Double.parseDouble(arrayStrings[3]),
					Integer.parseInt(arrayStrings[4]),
					Double.parseDouble(arrayStrings[5]),
					Double.parseDouble(arrayStrings[6]),
					Integer.parseInt(arrayStrings[7]),
					Double.parseDouble(arrayStrings[8]),
					Double.parseDouble(arrayStrings[9]),
					Short.parseShort(arrayStrings[10]),
					Integer.parseInt(arrayStrings[11]),
					Integer.parseInt(arrayStrings[12]),
					Integer.parseInt(arrayStrings[13]),
					Integer.parseInt(arrayStrings[14]),
					Integer.parseInt(arrayStrings[15]),
					Integer.parseInt(arrayStrings[16]),
					Double.parseDouble(arrayStrings[17]));
			lineInfos.add(info);
		}
		// System.out.println(lineInfos.size());
		reader.close();
		System.out.println(String.format(
				"Complete getting [%d] main records from input file.",
				lineInfos.size()));
		return lineInfos;
	}

	public List<ExtraFieldInfo> getExtraFields(String inputFile)
			throws IOException {
		List<ExtraFieldInfo> fieldInfos = new ArrayList<ExtraFieldInfo>();
		ExtraFieldInfo extraInfo = null;
		FileInputStream inputStream = new FileInputStream(inputFile);
		DataInputStream dataInputStream = new DataInputStream(inputStream);
		BufferedReader reader = new BufferedReader(new InputStreamReader(
				dataInputStream));
		String strLine;
		while ((strLine = reader.readLine()) != null) {
			if (strLine.contains(";")) {
				if (strLine.substring(1).trim().isEmpty()) {
					continue;
				}
				extraInfo = parseExtraFields(strLine);
				fieldInfos.add(extraInfo);
			} else {
				break;
			}
		}
		reader.close();
		System.out.println(String.format(
				"Complete getting [%d] extra records from input file.",
				fieldInfos.size()));
		return fieldInfos;
	}

	public void writeMainFieldIntoOutputFile(List<MainFieldInfo> infos,
			String outputFile) throws IOException {
		FileOutputStream fileOutputStream = new FileOutputStream(outputFile);
		DataOutputStream dataOutputStream = new DataOutputStream(
				fileOutputStream);
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
				dataOutputStream));		
		for (MainFieldInfo lineInfo : infos) {
			writer.write(String.format(
					"%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s",
					String.valueOf(lineInfo.id),
					String.valueOf(lineInfo.submit),
					String.valueOf(lineInfo.wait),
					String.valueOf(lineInfo.runtime),
					String.valueOf(lineInfo.size),
					String.valueOf(lineInfo.cpu), String.valueOf(lineInfo.mem),
					String.valueOf(lineInfo.reqsize),
					String.valueOf(lineInfo.estimate),
					String.valueOf(lineInfo.reqmem),
					String.valueOf(lineInfo.status),
					String.valueOf(lineInfo.uid), String.valueOf(lineInfo.gid),
					String.valueOf(lineInfo.executable),
					String.valueOf(lineInfo.queueid),
					String.valueOf(lineInfo.partition),
					String.valueOf(lineInfo.depjob),
					String.valueOf(lineInfo.think)));
			writer.write("\n");
			writer.flush();
		}
		writer.close();
		System.out
				.println("Write main information obtained into outputFile successfully.!!!");
	}

	public void writeExtraFieldIntoOutputFile(
			List<ExtraFieldInfo> extraFieldInfos, String output)
			throws IOException {
		FileOutputStream outputStream = new FileOutputStream(output);
		DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
				dataOutputStream));
		for (ExtraFieldInfo fieldInfo : extraFieldInfos) {
			writer.write(String.format("%s: %s", fieldInfo.getName(),
					fieldInfo.getValue()));
			writer.write("\n");
			writer.flush();
		}
		writer.close();
		System.out
				.println("Write extra information obtained into outputFile successfully.!!!");

	}

}
